<template>
  <div v-if="getShow">
    <LoginFormTitle class="enter-x" />
    <Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef">
      <Steps :current="formData.currentStep">
        <Step :title="t('sys.login.writeTitle')" />
        <Step :title="t('sys.login.confirmTitle')" />
        <Step :title="t('sys.login.completeTitle')" />
      </Steps>
      <div class="mt-5 step1" v-show="formData.currentStep === 0">
        <FormItem name="userNameType" class="enter-x">
          <RadioGroup
            size="large"
            v-model:value="formData.userNameType"
            :options="accountTypeOptions"
          />
        </FormItem>
        <FormItem name="userName" class="enter-x">
          <Input
            size="large"
            v-model:value="formData.userName"
            :placeholder="t('sys.login.userName')"
            class="fix-auto-fill"
          >
            <template #prefix>
              <Icon
                :icon="
                  formData.userNameType === '1' ? 'clarity-mobile-phone-solid' : 'carbon-email'
                "
              />
            </template>
          </Input>
        </FormItem>
        <Row class="enter-x" :gutter="16">
          <Col :span="6" />
          <Col :span="6">
            <Button block @click="handleBack">
              {{ t('sys.login.backSignIn') }}
            </Button>
          </Col>
          <Col :span="6">
            <Button type="primary" block :loading="loading" @click="handleStepNext">
              {{ t('sys.login.nextTitle') }}
            </Button>
          </Col>
          <Col :span="6" />
        </Row>
      </div>
      <div class="mt-5 step2" v-show="formData.currentStep === 1">
        <FormItem name="alertWarning" class="enter-x">
          <Alert
            type="warning"
            :message="`${t('sys.login.verifyResetPasswordText', [
              formData.userNameType === '1' ? accountTypeTitle.mobile : accountTypeTitle.email,
            ])}`"
            show-icon
          />
        </FormItem>
        <FormItem name="alertInfo" class="enter-x">
          <Alert
            type="info"
            :message="`${
              formData.userNameType === '1' ? accountTypeTitle.mobile : accountTypeTitle.email
            }：${formData.userName}`"
            show-icon
          />
        </FormItem>
        <FormItem name="smsCode" class="enter-x" v-show="formData.userNameType === '1'">
          <CountdownInput
            size="large"
            v-model:value="formData.smsCode"
            :placeholder="t('sys.login.smsCode')"
            :sendCodeApi="handleSmsVerifyCode"
            icon="tabler:device-mobile-message"
            class="fix-auto-fill"
          >
            <template #prefix>
              <Icon icon="tabler:device-mobile-message" />
            </template>
          </CountdownInput>
        </FormItem>
        <FormItem name="newPassword" class="enter-x" v-show="formData.userNameType === '1'">
          <StrengthMeter
            size="large"
            v-model:value="formData.newPassword"
            :placeholder="t('sys.login.password')"
          >
            <template #prefix>
              <Icon icon="simple-icons:1password" />
            </template>
          </StrengthMeter>
        </FormItem>
        <FormItem name="confirmPassword" class="enter-x" v-show="formData.userNameType === '1'">
          <InputPassword
            size="large"
            visibilityToggle
            v-model:value="formData.confirmPassword"
            :placeholder="t('sys.login.confirmPassword')"
          >
            <template #prefix>
              <Icon icon="carbon-password" />
            </template>
          </InputPassword>
        </FormItem>
        <FormItem name="verifyCode" class="enter-x" v-show="formData.userNameType === '2'">
          <CaptchaInput
            size="large"
            v-model:value="formData.verifyCode"
            :placeholder="t('sys.login.verifyCode')"
            :getCaptchaApi="refreshVerifyCode"
            icon="flat-color-icons:edit-image"
            class="fix-auto-fill"
          />
        </FormItem>
        <Row class="enter-x" :gutter="16">
          <Col :span="6" />
          <Col :span="6">
            <Button block @click="handleStepPrev">
              {{ t('sys.login.prevTitle') }}
            </Button>
          </Col>
          <Col :span="6">
            <Button type="primary" block :loading="loading" @click="handleSubmit">
              {{ t('sys.login.submitTitle') }}
            </Button>
          </Col>
          <Col :span="6" />
        </Row>
      </div>
      <div class="mt-5 step3" v-show="formData.currentStep === 2">
        <Result
          :status="resultData.status"
          :title="resultData.title"
          :sub-title="resultData.subTitle"
        >
          <template #extra>
            <a-button
              key="open"
              type="primary"
              :disabled="formData.userNameType !== '2' || resultData.status !== 'success'"
              @click="() => openMailSite(formData.userName)"
            >
              {{ t('sys.login.viewMailbox') }}
            </a-button>
            <a-button key="back" @click="handleBack" :loading="loading">
              {{ t('sys.login.backSignIn') }}
            </a-button>
          </template>
        </Result>
        <div>
          <Descriptions>
            <DescriptionItem>{{ '' }}</DescriptionItem>
          </Descriptions>
        </div>
      </div>
    </Form>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, ref, toRaw, computed, unref, watchEffect, h } from 'vue';

  import LoginFormTitle from './LoginFormTitle.vue';

  import {
    Form,
    Row,
    Col,
    Input,
    Button,
    Radio,
    Descriptions,
    Result,
    Steps,
    Step,
    Alert,
  } from 'ant-design-vue';
  import { CountdownInput } from '@/components/CountDown';
  import { CaptchaInput } from '@/components/Captcha';
  import { StrengthMeter } from '@/components/StrengthMeter';

  import { useI18n } from '@/hooks/web/useI18n';
  import { useDesign } from '@/hooks/web/useDesign';
  import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
  import { useMessage } from '@/hooks/web/useMessage';
  import { isMobileNumber } from '@/enums/regexEnum';
  import { sendSmsVerifyCode } from '@/api/sms';
  import { getVerifyCode } from '@/api/sys';
  import { sendResetPwdEmail, resetPwdByPhone } from '@/api/identity';
  import { openMailSite } from '@/utils/common';
  import Icon from '@/components/Icon/Icon.vue';

  interface ResultData {
    status: 'error' | 'success' | 'warning' | 'info' | '404' | '403' | '500';
    title: string;
    subTitle: string;
  }

  const FormItem = Form.Item;
  const InputPassword = Input.Password;
  const RadioGroup = Radio.Group;
  const DescriptionItem = Descriptions.Item;

  const { t } = useI18n();
  const { prefixCls } = useDesign('login');
  const { handleBackLogin, getLoginState, getUserAccountState } = useLoginState();
  const { createErrorModal } = useMessage();

  const formRef = ref();
  const loading = ref(false);

  const accountTypeTitle = { mobile: t('sys.login.mobile'), email: t('sys.login.email') };
  const accountTypeOptions = [
    { label: accountTypeTitle.mobile, value: '1' },
    { label: accountTypeTitle.email, value: '2' },
  ];

  const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD);

  const formData = reactive({
    currentStep: 0,
    userNameType: '1',
    userName: '',
    smsCode: '',
    smsCodeId: '',
    newPassword: '',
    confirmPassword: '',
    verifyCode: '',
    verifyCodeId: '',
  });
  const resultData = reactive<ResultData>({
    status: 'info',
    title: t('common.processingText'),
    subTitle: '',
  });
  const { getFormRules } = useFormRules(formData);
  const { validForm } = useFormValid(formRef);

  watchEffect(() => {
    const userAccountState = computed(() => unref(getUserAccountState));
    formData.userName = userAccountState.value;
  });

  /** 处理短信验证码 */
  async function handleSmsVerifyCode() {
    if (formData.userName === undefined || formData.userName === null || formData.userName === '') {
      showErrorModal(t('sys.api.errorTip'), t('sys.login.mobilePlaceholder'));
      return false;
    }
    if (!isMobileNumber(formData.userName)) {
      showErrorModal(t('sys.api.errorTip'), t('sys.login.mobileFormatError'));
      return false;
    }
    try {
      const dto = toRaw({ PhoneNumber: formData.userName, mode: 'none' });
      const ajaxResult = await sendSmsVerifyCode(dto);
      if (!ajaxResult.Succeeded) {
        showErrorModal(t('sys.api.errorTip'), ajaxResult.Content);
        return false;
      }
      formData.smsCodeId = ajaxResult.Data as string;
      return true;
    } catch (error: any) {
      showErrorModal(t('sys.api.errorTip'), error?.message || t('sys.api.networkExceptionMsg'));
      return false;
    }
  }

  /** 刷新验证码 */
  async function refreshVerifyCode() {
    const verifyCodeDto = await getVerifyCode();
    formData.verifyCodeId = verifyCodeDto.Id;
    return verifyCodeDto.Image;
  }

  /** 处理返回 */
  async function handleBack() {
    clearFormData();
    handleBackLogin();
  }

  /** 处理上一步 */
  async function handleStepPrev() {
    formData.currentStep--;
  }

  /** 处理下一步 */
  async function handleStepNext() {
    const data = await validForm();
    if (!data) return;
    try {
      loading.value = true;
      formData.currentStep++;
    } finally {
      loading.value = false;
    }
  }

  /** 处理提交 */
  async function handleSubmit() {
    const data = await validForm();
    if (!data) return;
    try {
      loading.value = true;
      if (formData.userNameType === '1') {
        const dto = toRaw({
          PhoneNumber: formData.userName,
          SmsCode: formData.smsCode,
          SmsCodeId: formData.smsCodeId,
          NewPassword: formData.newPassword,
          ConfirmPassword: formData.confirmPassword,
        });
        const ajaxResult = await resetPwdByPhone(dto, 'none');
        if (ajaxResult.Succeeded) {
          resultData.status = 'success';
          resultData.title = t('sys.login.resetPasswordSuccess');
          resultData.subTitle = `${ajaxResult.Content}      “${t(
            'sys.email.resetPasswordSuccessDesc',
          )}”`;
        } else {
          resultData.status = 'error';
          resultData.title = t('sys.login.resetPasswordFailed');
          resultData.subTitle = `${ajaxResult.Content}      “${t(
            'sys.login.verifyResetPasswordText',
            [accountTypeTitle.mobile],
          )}”`;
        }
      }
      if (formData.userNameType === '2') {
        const dto = toRaw({
          Email: formData.userName,
          EmailConfirmUrl: `${window.location.origin}/#/reset-password`,
          VerifyCode: formData.verifyCode,
          VerifyCodeId: formData.verifyCodeId,
        });
        const ajaxResult = await sendResetPwdEmail(dto, 'none');
        if (ajaxResult.Succeeded) {
          resultData.status = 'success';
          resultData.title = t('sys.login.resetPasswordSuccess');
          resultData.subTitle = `${ajaxResult.Content}      “${t('sys.login.resetPasswordEmail')}”`;
        } else {
          resultData.status = 'error';
          resultData.title = t('sys.login.resetPasswordFailed');
          resultData.subTitle = `${ajaxResult.Content}      “${t(
            'sys.login.verifyResetPasswordText',
            [accountTypeTitle.email],
          )}”`;
        }
      }
    } catch (error: any) {
      resultData.status = 'error';
      resultData.title = t('sys.login.resetPasswordFailed');
      resultData.subTitle = `${error?.message}      “${t('sys.login.verifyResetPasswordText', [
        formData.userNameType === '1' ? accountTypeTitle.mobile : accountTypeTitle.email,
      ])}”`;
    } finally {
      loading.value = false;
      formData.currentStep++;
    }
  }

  /** 清除表单数据 */
  function clearFormData() {
    formData.currentStep = 0;
    formData.userNameType = '1';
    formData.userName = '';
    formData.smsCode = '';
    formData.smsCodeId = '';
    formData.newPassword = '';
    formData.confirmPassword = '';
    formData.verifyCode = '';
    formData.verifyCodeId = '';
    resultData.status = 'info';
    resultData.title = t('common.processingText');
    resultData.subTitle = '';
  }

  function showErrorModal(title: string, content: string) {
    createErrorModal({
      title: () => h('span', title),
      content: () => h('span', content),
      getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
    });
  }
</script>

<style lang="less" scoped>
  // .step1 {
  //   max-width: 500px;
  // }

  // .step2 {
  //   max-width: 500px;
  // }

  // .step3 {
  //   max-width: 500px;
  // }
</style>
